package com.gamejelly.proxy.client;

import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

public interface LoadBalance {
    String ROUND = "round";
    String RANDOM = "random";

    static LoadBalance build(String strategy, String... address) {
        if (address.length > 1) {
            switch (strategy) {
                case ROUND:
                    return new Round(address);
                case RANDOM:
                    return new Random(address);
                default:
                    return new Round(address);
            }
        } else if (address.length == 1)
            return new Direct(address[0]);
        else
            return null;
    }

    String next();

    class Direct implements LoadBalance {
        private final String address;

        public Direct(String address) {
            this.address = address;
        }

        @Override
        public String next() {
            return address;
        }
    }

    class Round implements LoadBalance {
        private final String[] addresses;

        public volatile int index;
        public static final AtomicIntegerFieldUpdater<Round> INDEX = AtomicIntegerFieldUpdater.newUpdater(Round.class, "index");

        public Round(String... address) {
            this.addresses = address;
        }

        @Override
        public String next() {
            int length = addresses.length;
            int idx = INDEX.getAndIncrement(this);
            if (idx >= length) {
                INDEX.set(this, 0);
                idx = length;
            }
            return addresses[idx];
        }
    }

    class Random implements LoadBalance {
        private final String[] addresses;

        public Random(String... address) {
            this.addresses = address;
        }

        @Override
        public String next() {
            int r = new java.util.Random().nextInt(addresses.length);
            return addresses[r];
        }
    }


}
